package com.xjrsoft.module.buildCode.grant;

import cn.hutool.core.map.MapUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.toolkit.BeanUtils;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert;
import com.baomidou.mybatisplus.generator.config.converts.OracleTypeConvert;
import com.baomidou.mybatisplus.generator.config.converts.PostgreSqlTypeConvert;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.xjrsoft.common.converter.XjrSqlServerTypeConvert;
import com.xjrsoft.core.tool.utils.*;
import com.xjrsoft.module.buildCode.config.InjectionConfig;
import com.xjrsoft.module.buildCode.dto.*;
import com.xjrsoft.module.buildCode.utils.BuildCodeUtil;
import com.xjrsoft.module.form.constant.FormConstants;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 代码生成器配置类
 *
 * @author Chill
 */
@Data
@Slf4j
public class XjrCodeGenerator {

	private Boolean isWebModule = true;

	/**
	 * 代码模块名称
	 */
	private String codeName;
	/**
	 * 代码所在服务名
	 */
	private String serviceName = "xjr-service";
	/**
	 * 代码生成的包名
	 */
	private String packageName = "com.xjrsoft.test";
	/**
	 * 代码后端生成的地址
	 */
	private String packageDir;
	/**
	 * 代码前端生成的地址
	 */
	private String packageWebDir;
	/**
	 * 需要去掉的表前缀
	 */
	private String[] tablePrefix = {""};
	/**
	 * 是否包含基础业务字段
	 */
	private Boolean hasSuperEntity = Boolean.FALSE;
	/**
	 * 是否包含包装器
	 */
	private Boolean hasWrapper = Boolean.FALSE;
	/**
	 * 基础业务字段
	 */
	private String[] superEntityColumns = {"create_time", "create_user", "create_dept", "update_time", "update_user", "status", "is_deleted"};
//	/**
//	 * 租户字段
//	 */
//	private String tenantColumn = "tenant_id";
	/**
	 * 是否启用swagger
	 */
	private Boolean isSwagger2 = Boolean.TRUE;
	/**
	 * 数据库驱动名
	 */
	private String driverName;
	/**
	 * 数据库链接地址
	 */
	private String url;
	/**
	 * 数据库用户名
	 */
	private String username;
	/**
	 * 数据库密码
	 */
	private String password;

	/**
	 * 数据库类型
	 */
	private DbType dbType;

	private Map<String, Object> params;

	private Map<String, String> resultCodeMap = new HashMap<>(16);

	private XjrTemplateEngine templateEngine;

	/**
	 *
	 * @param codeSchemaDto
	 * @param isWriteCode 是否写入文件
	 */
	public void run(CodeSchemaDto codeSchemaDto, boolean isWriteCode, boolean isDynamicData) {
		BaseInfoDto baseInfoDto = codeSchemaDto.getBaseInfoDto();

		List<String> includeTableList = codeSchemaDto.getDbTableDtoList().stream().map(table -> table.getName()).collect(Collectors.toList());
		AutoGenerator mpg = new AutoGenerator();
		GlobalConfig gc = new GlobalConfig();
		String outputDir = getOutputDir();
		gc.setOutputDir(outputDir);
		gc.setAuthor(codeSchemaDto.getBaseInfoDto().getCreateUser());
		gc.setFileOverride(true);
		gc.setOpen(false);
		gc.setActiveRecord(false);
		gc.setEnableCache(false);
		gc.setBaseResultMap(true);
		gc.setBaseColumnList(true);
		gc.setMapperName("%sMapper");
		gc.setXmlName("%sMapper");
		gc.setServiceName("I%sService");
		gc.setServiceImplName("%sServiceImpl");
		gc.setControllerName("%sController");
		gc.setSwagger2(isSwagger2);
		mpg.setGlobalConfig(gc);
		// 策略配置
		StrategyConfig strategy = new StrategyConfig();
		// strategy.setCapitalMode(true);// 全局大写命名
		// strategy.setDbColumnUnderline(true);//全局下划线命名
		strategy.setNaming(NamingStrategy.underline_to_camel);
		strategy.setColumnNaming(NamingStrategy.underline_to_camel);
		strategy.setTablePrefix(tablePrefix);
		if (includeTableList.size() > 0) {
			strategy.setInclude(includeTableList.toArray(new String[]{}));
		}
		if (hasSuperEntity) {
			strategy.setSuperEntityClass("com.xjrsoft.core.mp.base.BaseEntity");
			strategy.setSuperEntityColumns(superEntityColumns);
			strategy.setSuperServiceClass("com.xjrsoft.core.mp.base.BaseService");
			strategy.setSuperServiceImplClass("com.xjrsoft.core.mp.base.BaseServiceImpl");
		} else {
			strategy.setSuperServiceClass("com.baomidou.mybatisplus.extension.service.IService");
			strategy.setSuperServiceImplClass("com.xjrsoft.core.mp.base.BaseService");
		}
		strategy.setEntityBuilderModel(false);
		strategy.setEntityLombokModel(true);
		strategy.setControllerMappingHyphenStyle(true);
		strategy.setEntityTableFieldAnnotationEnable(true);
//		strategy.setNameConvert(new XjrNameConvert());
		mpg.setStrategy(strategy);

		if (isDynamicData) {
			mpg.setTableInfoList(BuildCodeUtil.buildTableInfoList(codeSchemaDto.getTableInfoDtoList(), dbType, strategy, gc));
		} else {
			DataSourceConfig dsc = new DataSourceConfig();
			DynamicDataSourceProperties dataSourceProperties = SpringUtil.getBean(DynamicDataSourceProperties.class);
			DataSourceProperty dataSourceProperty = dataSourceProperties.getDatasource().get(dataSourceProperties.getPrimary());
			String driverName = Func.toStr(this.driverName, dataSourceProperty.getDriverClassName());
			if (dbType == DbType.MYSQL) {
				dsc.setTypeConvert(new MySqlTypeConvert());
				driverName = "com.mysql.cj.jdbc.Driver";
			} else if (dbType == DbType.POSTGRE_SQL) {
				dsc.setTypeConvert(new PostgreSqlTypeConvert());
				driverName = "org.postgresql.Driver";
			} else if (dbType == DbType.SQL_SERVER || dbType == DbType.SQL_SERVER2005) {
				dsc.setTypeConvert(new XjrSqlServerTypeConvert());
				driverName = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
			} else {
				dsc.setTypeConvert(new OracleTypeConvert());
				driverName = "oracle.jdbc.driver.OracleDriver";
			}
//			dsc.setDbType(dbType);
			dsc.setDriverName(driverName);
			dsc.setUrl(Func.toStr(this.url, dataSourceProperty.getUrl()));
			dsc.setUsername(Func.toStr(this.username, dataSourceProperty.getUsername()));
			dsc.setPassword(Func.toStr(this.password, dataSourceProperty.getPassword()));
			mpg.setDataSource(dsc);
		}
		// 包配置
		PackageConfig pc = new PackageConfig();
		// 控制台扫描
		pc.setModuleName(null);
		pc.setParent(packageName);
		pc.setController("controller");
		pc.setEntity("entity");
		pc.setXml("mapper");
		mpg.setPackageInfo(pc);
		mpg.setCfg(getInjectionConfig(includeTableList.size()));
		// 设置模板引擎
		this.templateEngine = buildTemplateEngine(codeSchemaDto);
		// 是否预览代码，不写入文件
		templateEngine.setWriteCode(isWriteCode);
		mpg.setTemplateEngine(templateEngine);
		mpg.execute();
		// 生成list页面代码
		if (isWebModule) {
			String pk = BuildCodeUtil.findPk(this);
			String listCode = genListViewCode(pk, baseInfoDto, codeSchemaDto.getQueryDataDtoList(), codeSchemaDto.getColDataDto(), codeSchemaDto.getTotalDataDto(), codeSchemaDto.getFormDataDtoList());
			if (!isWriteCode) {
				resultCodeMap.put("listHTML", listCode);
			}
		}
		resultCodeMap.putAll(buildResultCode(templateEngine.getResultCodeMap()));
	}

	private InjectionConfig getInjectionConfig(Integer entityCount) {
		String servicePackage = serviceName.split("-").length > 1 ? serviceName.split("-")[1] : serviceName;
		// 自定义配置
		Map<String, Object> map = new HashMap<>(16);
		InjectionConfig cfg = new InjectionConfig() {
			@Override
			public void initMap() {
				map.put("codeName", codeName);
				map.put("serviceName", serviceName);
				map.put("servicePackage", StringUtil.lowerFirst(servicePackage));
//				map.put("tenantColumn", tenantColumn);
				map.put("hasWrapper", hasWrapper);
				this.setMap(map);
			}
		};
		List<FileOutConfig> focList = new ArrayList<>();
//		focList.add(new FileOutConfig("/templates/sql/menu.sql.vm") {
//			@Override
//			public String outputFile(TableInfo tableInfo) {
//				map.put("entityKey", (tableInfo.getEntityName().toLowerCase()));
//				map.put("menuId", IdWorker.getId());
//				map.put("addMenuId", IdWorker.getId());
//				map.put("editMenuId", IdWorker.getId());
//				map.put("removeMenuId", IdWorker.getId());
//				map.put("viewMenuId", IdWorker.getId());
//				return getOutputDir() + "/" + "/sql/" + tableInfo.getEntityName().toLowerCase() + ".menu.mysql";
//			}
//		});
		focList.add(new FileOutConfig("/templates/entityVo.java.vm") {
			@Override
			public String outputFile(TableInfo tableInfo) {
				return getOutputDir() + "/" + packageName.replace(".", "/") + "/" + "vo" + "/" + tableInfo.getEntityName() + "Vo" + StringPool.DOT_JAVA;
			}
		});
		focList.add(new FileOutConfig("/templates/entityDto.java.vm") {
			@Override
			public String outputFile(TableInfo tableInfo) {
				return getOutputDir() + "/" + packageName.replace(".", "/") + "/" + "dto" + "/" + tableInfo.getEntityName() + "Dto" + StringPool.DOT_JAVA;
			}
		});
		focList.add(new FileOutConfig("/templates/saveFormDataDto.java.vm") {
			@Override
			public String outputFile(TableInfo tableInfo) {
				return getOutputDir() + "/" + packageName.replace(".", "/") + "/" + "dto" + "/Save" + tableInfo.getEntityName() + "FormDataDto" + StringPool.DOT_JAVA;
			}
		});
		if (entityCount > 1) {
			focList.add(new FileOutConfig("/templates/formDataVo.java.vm") {
				@Override
				public String outputFile(TableInfo tableInfo) {
					return getOutputDir() + "/" + packageName.replace(".", "/") + "/" + "vo" + "/" + tableInfo.getEntityName() + "FormDataVo" + StringPool.DOT_JAVA;
				}
			});
		}

		focList.add(new FileOutConfig("/templates/listVo.java.vm") {
			@Override
			public String outputFile(TableInfo tableInfo) {
				return getOutputDir() + "/" + packageName.replace(".", "/") + "/" + "vo" + "/" + tableInfo.getEntityName() + "ListVo" + StringPool.DOT_JAVA;
			}
		});
		focList.add(new FileOutConfig("/templates/listDto.java.vm") {
			@Override
			public String outputFile(TableInfo tableInfo) {
				return getOutputDir() + "/" + packageName.replace(".", "/") + "/" + "dto" + "/" + tableInfo.getEntityName() + "ListDto" + StringPool.DOT_JAVA;
			}
		});
		if (Func.isNotBlank(packageWebDir)) {
			if (Func.equals("systemName", "DevelopConstant.SWORD_NAME")) {
				focList.add(new FileOutConfig("/templates/sword/action.js.vm") {
					@Override
					public String outputFile(TableInfo tableInfo) {
						return getOutputWebDir() + "/actions" + "/" + tableInfo.getEntityName().toLowerCase() + ".js";
					}
				});
				focList.add(new FileOutConfig("/templates/sword/model.js.vm") {
					@Override
					public String outputFile(TableInfo tableInfo) {
						return getOutputWebDir() + "/models" + "/" + tableInfo.getEntityName().toLowerCase() + ".js";
					}
				});
				focList.add(new FileOutConfig("/templates/sword/service.js.vm") {
					@Override
					public String outputFile(TableInfo tableInfo) {
						return getOutputWebDir() + "/services" + "/" + tableInfo.getEntityName().toLowerCase() + ".js";
					}
				});
				focList.add(new FileOutConfig("/templates/sword/list.js.vm") {
					@Override
					public String outputFile(TableInfo tableInfo) {
						return getOutputWebDir() + "/pages" + "/" + StringUtil.upperFirst(servicePackage) + "/" + tableInfo.getEntityName() + "/" + tableInfo.getEntityName() + ".js";
					}
				});
				focList.add(new FileOutConfig("/templates/sword/add.js.vm") {
					@Override
					public String outputFile(TableInfo tableInfo) {
						return getOutputWebDir() + "/pages" + "/" + StringUtil.upperFirst(servicePackage) + "/" + tableInfo.getEntityName() + "/" + tableInfo.getEntityName() + "Add.js";
					}
				});
				focList.add(new FileOutConfig("/templates/sword/edit.js.vm") {
					@Override
					public String outputFile(TableInfo tableInfo) {
						return getOutputWebDir() + "/pages" + "/" + StringUtil.upperFirst(servicePackage) + "/" + tableInfo.getEntityName() + "/" + tableInfo.getEntityName() + "Edit.js";
					}
				});
				focList.add(new FileOutConfig("/templates/sword/view.js.vm") {
					@Override
					public String outputFile(TableInfo tableInfo) {
						return getOutputWebDir() + "/pages" + "/" + StringUtil.upperFirst(servicePackage) + "/" + tableInfo.getEntityName() + "/" + tableInfo.getEntityName() + "View.js";
					}
				});
			} else if (Func.equals("systemName", "DevelopConstant.SABER_NAME")) {
				focList.add(new FileOutConfig("/templates/saber/api.js.vm") {
					@Override
					public String outputFile(TableInfo tableInfo) {
						return getOutputWebDir() + "/api" + "/" + servicePackage.toLowerCase() + "/" + tableInfo.getEntityName().toLowerCase() + ".js";
					}
				});
				focList.add(new FileOutConfig("/templates/saber/crud.vue.vm") {
					@Override
					public String outputFile(TableInfo tableInfo) {
						return getOutputWebDir() + "/views" + "/" + servicePackage.toLowerCase() + "/" + tableInfo.getEntityName().toLowerCase() + ".vue";
					}
				});
			}
		}
		cfg.setFileOutConfigList(focList);
		return cfg;
	}

	/**
	 * 生成到项目中
	 *
	 * @return outputDir
	 */
	public String getOutputDir() {
		return (Func.isBlank(packageDir) ? System.getProperty("user.dir") : packageDir) + "/src/main/java";
	}

	/**
	 * 生成到Web项目中
	 *
	 * @return outputDir
	 */
	public String getOutputWebDir() {
		return (Func.isBlank(packageWebDir) ? System.getProperty("user.dir") : packageWebDir) + "/src";
	}

	/**
	 * 页面生成的文件名
	 */
	private String getGeneratorViewPath(String viewOutputDir, TableInfo tableInfo, String suffixPath) {
		String name = StringUtil.lowerFirst(tableInfo.getEntityName());
		String path = viewOutputDir + "/" + name + "/" + name + suffixPath;
		File viewDir = new File(path).getParentFile();
		if (!viewDir.exists()) {
			viewDir.mkdirs();
		}
		return path;
	}

	/**
	 * 构建模板引擎
	 *
	 * @param codeSchemaDto
	 * @return
	 */
	private XjrTemplateEngine buildTemplateEngine(CodeSchemaDto codeSchemaDto) {
		XjrTemplateEngine templateEngine = new XjrTemplateEngine();
		List<DbTableDto> dbTableDtoList = codeSchemaDto.getDbTableDtoList();
		String mainTableName = StringPool.EMPTY;
		for (DbTableDto dbTableDto : dbTableDtoList) {
			if (dbTableDto.isMainTable()) mainTableName = dbTableDto.getName();
		}
		templateEngine.setDbLinkId(codeSchemaDto.getDbLinkId());
		templateEngine.setMainTableName(mainTableName);
		templateEngine.setTableList(BeanUtils.beansToMaps(dbTableDtoList));
		List<Map<String, Object>> formDataDtoList = codeSchemaDto.getFormDataDtoList();
		List<Map<String, String>> mainTableFieldList = new ArrayList<>();
		Map<String, List<Map<String, String>>> tableFielListdMap = new HashMap<>(dbTableDtoList.size());
		tableFielListdMap.put(mainTableName, mainTableFieldList);
		// 查询字段
		List<QueryDataDto> queryDataDtoList = codeSchemaDto.getQueryDataDtoList();
		List<Map<String, String>> queryFieldList = new ArrayList<>(queryDataDtoList.size());
		// 列表字段
		ColDataDto colDataDto = codeSchemaDto.getColDataDto();

		List<Map<String, Object>> colDataList = colDataDto.getColumnList();
		List<Map<String, String>> columnList = new ArrayList<>(colDataList.size());
		Map<String, String> subSortFieldMap = new HashMap<>();
		Map<String, List<Map<String, String>>> lazyFieldMap = new HashMap<>();
		for (Map<String, Object> formDataDto : formDataDtoList) {
			Map<String, Object> config = MapUtils.getMap(formDataDto, FormConstants.CONFIG);
			String componentName = MapUtils.getString(config, "componentName");
			if (StringUtil.equalsIgnoreCase(componentName, "avue-tabs")) {
				Map<String, Object> tabsMap = MapUtils.getMap(config, "childrenObj");
				for (Object tabObj: tabsMap.values()) {
					Collection<Map<String, Object>> tabComponents = (Collection<Map<String, Object>>) tabObj;
					for (Map<String, Object> tabComponent : tabComponents) {
						parseFieldData(templateEngine, tabComponent, tableFielListdMap, lazyFieldMap, subSortFieldMap, mainTableFieldList, queryDataDtoList, queryFieldList, columnList, colDataDto.getColumnList());
					}
				}
			} else {
				parseFieldData(templateEngine, formDataDto, tableFielListdMap, lazyFieldMap, subSortFieldMap, mainTableFieldList, queryDataDtoList, queryFieldList, columnList, colDataDto.getColumnList());
			}
		}
		// 子表排序字段
		templateEngine.setSubSortFieldMap(subSortFieldMap);
		// 查询字段
		templateEngine.setQueryFieldList(queryFieldList);
		// 列表字段
		templateEngine.setColumnList(columnList);
		templateEngine.setTableFieldListMap(tableFielListdMap);
		templateEngine.setLazyFieldMap(lazyFieldMap);
		templateEngine.setPage(StringUtil.equals(colDataDto.getIsPage(), "1"));
		boolean isTree = colDataDto.getIsTree() != null && colDataDto.getIsTree() == 1;
		templateEngine.setTree(isTree);
		// 是否用于工作流
		Boolean isWorkflowForm = codeSchemaDto.getBaseInfoDto().getIsWorkflowForm();
		templateEngine.setWorkflowForm(isWorkflowForm == null ? false : isWorkflowForm);
		if (isTree) {
			templateEngine.setTreeForm(colDataDto.getTreeForm());
		}
		ModuleDataDto moduleDataDto = codeSchemaDto.getModuleDataDto();
		if (moduleDataDto != null) {
			templateEngine.setModuleName(moduleDataDto.getFullName());
		} else {
			templateEngine.setModuleName(codeSchemaDto.getBaseInfoDto().getDescribe());
		}
		ImportDataDto importDataDto = colDataDto.getImportDataDto();
		if (importDataDto != null && CollectionUtil.isNotEmpty(importDataDto.getImportFieldsDtoList())) {
			templateEngine.setImport(true);
		}
		templateEngine.setOnlyFont(codeSchemaDto.getBaseInfoDto().getIsOnlyFont());

		return templateEngine;
	}

	public void parseFieldData(XjrTemplateEngine templateEngine, Map<String, Object> tabComponent, Map<String, List<Map<String, String>>> tableFieldListdMap, Map<String, List<Map<String, String>>> lazyFieldMap, Map<String, String> subSortFieldMap,
							   List<Map<String, String>> mainTableFieldList, List<QueryDataDto> queryDataDtoList, List<Map<String, String>> queryFieldList,
							   List<Map<String, String>> columnList, List<Map<String, Object>> columnDtoList) {
		Map<String, Object> config = MapUtils.getMap(tabComponent, FormConstants.CONFIG);;
		String infoType = MapUtils.getString(tabComponent, FormConstants.FIELD_TYPE_OF_INFO_TYPE);
		String componentType = MapUtils.getString(tabComponent, FormConstants.FIELD_TYPE);
		String fieldName = MapUtils.getString(config, FormConstants.BIND_TABLE_FIELD);
		String tableName = MapUtils.getString(config, FormConstants.BIND_TABLE);
		Object childrenObj = config.get("children");
		if (StringUtil.isEmpty(fieldName) && childrenObj == null && !CollectionUtil.isNotEmpty((Collection<?>) childrenObj)) {
			return;
		}
		boolean isTrans = templateEngine.isTrans();
		String avueType = MapUtils.getString(config, "avueType");
		String tag = MapUtils.getString(config, "tag");
		// 设置自动编码配置
		if (StringUtil.equalsIgnoreCase(avueType, "autoCode")) {
			templateEngine.setCodeRule(Func.toStr(config.get("autoCodeRule")));
		}
		if (childrenObj != null) {
			boolean isSort = !MapUtils.getBoolean(config, "useDefaultSort", false);
			Integer sortFieldId = MapUtils.getInteger(config, "sortField");
			List<Map<String, String>> subTableFiledList = new ArrayList<>();
			List<Map<String, Object>> childrenList = (List<Map<String, Object>>) childrenObj;
			String subTableName = MapUtils.getString(config, "bindTable");
			for (Map<String, Object> field : childrenList) {
				Map<String, Object> subConfig = (Map<String, Object>) field.get("__config__");
				String subFieldName = MapUtils.getString(subConfig, "bindTableField");
				Map<String, String> subField = new HashMap<>();
				subField.put("fieldName", subFieldName);
				if (StringUtil.equalsIgnoreCase(MapUtils.getString(config, "avueType"), "datetime")) {
					field.put("type", "datetime");
					field.put("format", MapUtils.getString(tabComponent, "format"));
				}
				subTableFiledList.add(subField);
				if (isSort && (sortFieldId == MapUtils.getInteger(subConfig, "formId"))) {
					subSortFieldMap.put(MapUtils.getString(config, "bindTable"), subFieldName);
				}
				buildLazyMap(lazyFieldMap, MapUtils.getString(field, FormConstants.FIELD_TYPE_OF_INFO_TYPE), MapUtils.getString(field, FormConstants.FIELD_TYPE), subFieldName, subTableName);
			}
			tableFieldListdMap.put(subTableName, subTableFiledList);
		} else {
			Map<String, String> field = new HashMap<>();
			field.put("fieldName", fieldName);
			if (StringUtil.equalsIgnoreCase(avueType, "datetime")) {
				field.put("type", "datetime");
				field.put("format", MapUtils.getString(tabComponent, "format"));
			}
			mainTableFieldList.add(field);
			buildLazyMap(lazyFieldMap, infoType, componentType, fieldName, tableName);
		}

		// 查询字段
		if (CollectionUtil.isNotEmpty(queryDataDtoList)) {
			for (QueryDataDto queryDataDto : queryDataDtoList) {
				String queryFieldName = StringUtil.equalsIgnoreCase(queryDataDto.getSearchtype(), "time") ? queryDataDto.getDateField() : queryDataDto.getField();
				if (queryDataDto.getIsDate() != null && queryDataDto.getIsDate()
						&& StringUtil.equals(fieldName, queryFieldName) && !StringUtil.isEmpty(fieldName)) {
					Map<String, String> queryField = new HashMap<>(4);
					queryField.put("fieldName", queryFieldName);
					queryField.put("queryType", BuildCodeUtil.getQueryType(Func.toStr(config.get("avueType"))));
					queryFieldList.add(queryField);
				}
			}
		}

		// 列表字段
		for (Map<String, Object> columnMap: columnDtoList) {
			String columnName = MapUtils.getString(columnMap, "bindColumn");
			if (StringUtil.equals(fieldName, columnName)) {
//				String componentType = formDataDto.getComponentType();
				Map<String, String> columnField = new HashMap<>(16);
				columnField.put("columnName", columnName);
				String multi = StringPool.FALSE;
				if (StringUtil.equals(avueType, "select") ||
						StringUtil.equals(avueType, "radio") ||
						StringUtil.equals(avueType, "checkbox") ||
						StringUtil.equals(avueType, "asso-select") ||
						StringUtil.equals(avueType, "mutiple-popup") ||
						StringUtil.equals(avueType, "asso-popup")) {
					String dataType = MapUtils.getString(config, "dataType");
					columnField.put("dataType", dataType);
					columnField.put("dataItem", MapUtils.getString(config, "dataItem"));
					columnField.put("sql", StringUtils.replace(MapUtils.getString(config, "sql"), "\"", "\\\""));
					columnField.put("database", MapUtils.getString(config, "database"));
					columnField.put("dataSource", MapUtils.getString(config, "dataSource"));
					columnField.put("showField", MapUtils.getString(config, "showField"));
					columnField.put("saveField", MapUtils.getString(config, "saveField"));
					if (StringUtil.equalsIgnoreCase(dataType, "dataApi")) {
						Map<String, Object> apiConfig = MapUtils.getMap(config, "apiConfig");
						String prefix = MapUtils.getString(apiConfig, "dataSource");
						columnField.put("sql", prefix);
						columnField.put("id", MapUtils.getString(apiConfig, "id"));
						columnField.put("showField", MapUtils.getString(apiConfig, "showField"));
						columnField.put("saveField", MapUtils.getString(apiConfig, "saveField"));
					}
					if (!isTrans) isTrans = true;
				} else if (StringUtil.equals(componentType, "info") ||
						StringUtil.equals(componentType, "company") ||
						StringUtil.equals(componentType, "department") ||
						StringUtil.equals(componentType, "user")) {
					columnField.put("dataType", StringUtil.equals(componentType, "info") ? infoType : componentType);
					if (!isTrans) isTrans = true;
				} else if (StringUtil.equalsIgnoreCase(avueType, "select-area")) {
					columnField.put("dataType", "area");
					if (!isTrans) isTrans = true;
				} else if (StringUtil.equalsIgnoreCase(avueType, "datetime")) {
					// 日期时间格式化
					columnField.put("dataType", "datetime");
					String pattern = null;
					if (StringUtil.equalsIgnoreCase(MapUtils.getString(tabComponent, "type"),"week")) {
						pattern = "yyyy 第w周";
					} else {
						pattern = MapUtils.getString(tabComponent, "format");
					}
					columnField.put("pattern", pattern);
				} else if (StringUtil.equalsIgnoreCase(avueType, "number")) {
					Integer precision = MapUtils.getInteger(tabComponent, "precision");
					if (precision != null) {
						columnField.put("dataType", "number");
						columnField.put("pattern", "#0." + StringUtils.substring("000000000000000", 0, precision));
					}
				} else if (StringUtil.equalsIgnoreCase(avueType, "cascader")) {
					columnField.put("dataType", "cascade");
					columnField.put("separator", MapUtils.getString(tabComponent, "separator"));
					if (MapUtils.getBoolean(tabComponent, "show-all-levels")) {
						columnField.put("multi", StringPool.TRUE);
					}
					List<Map<String, Object>> settings = (List<Map<String, Object>>) config.get("settings");
					String datasourceIds = StringPool.EMPTY;
					String showFields = StringPool.EMPTY;
					String saveField = StringPool.EMPTY;
					for (int i = 0; i < settings.size(); i++ ) {
						Map<String, Object> setting = settings.get(i);
						if (i > 0) {
							datasourceIds += ",";
							showFields += ",";
							saveField += ",";
						}
						datasourceIds += "\"" + MapUtils.getString(setting, "dataSource") + "\"";
						showFields += "\"" + MapUtils.getString(setting, "showField") + "\"";
						saveField += "\"" + MapUtils.getString(setting, "saveField") + "\"";
					}
					multi = MapUtils.getBoolean(tabComponent, "show-all-levels") ? StringPool.TRUE : StringPool.FALSE;
					columnField.put("datasourceIds", "{" + datasourceIds + "}");
					columnField.put("showFields", "{" + showFields + "}");
					columnField.put("savedFields", "{" + saveField + "}");
					if (!isTrans) isTrans = true;
				}/* else if (MapUtils.getBoolean(tabComponent, "isCapitalized", false)) {
					columnField.put("dataType", "ch_yuan");
					if (!isTrans) isTrans = true;
				} */else if (StringUtil.equalsIgnoreCase(avueType, "password")) {
					columnField.put("dataType", "password");
					if (!isTrans) isTrans = true;
				} else if (StringUtil.equalsIgnoreCase(avueType, "upload") || StringUtil.equalsIgnoreCase(tag, "el-image")) {
					columnField.put("dataType", "file");
					if (!isTrans) isTrans = true;
				}
				if (StringUtil.equalsIgnoreCase(avueType, "checkbox") || StringUtil.equalsIgnoreCase(componentType, "user")
						|| StringUtil.equalsIgnoreCase(avueType, "select-area") || StringUtil.equalsIgnoreCase(avueType, "mutiple-popup")) {
					multi = StringPool.TRUE;
				}
				columnField.put("multi", multi);
				columnList.add(columnField);
			}
		}
		templateEngine.setTrans(isTrans);
	}

	/**
	 * 构建懒加载组件参数
	 * @param lazyFieldMap
	 * @param infoType
	 * @param componentType
	 * @param fieldName
	 * @param tableName
	 */
	private void buildLazyMap(Map<String, List<Map<String, String>>> lazyFieldMap, String infoType, String componentType, String fieldName, String tableName) {
		if (StringUtils.equalsIgnoreCase(componentType, "department") || StringUtils.equalsIgnoreCase(componentType, "company")
				|| (StringUtils.equalsIgnoreCase(componentType, "info") && (StringUtils.equalsIgnoreCase(infoType, "company") || StringUtils.equalsIgnoreCase(infoType, "department")))) {
			List<Map<String, String>> list = lazyFieldMap.get(tableName);
			if (list == null) {
				list = new ArrayList<>();
				lazyFieldMap.put(tableName, list);
			}
			Map<String, String> map = new HashMap<>();
			map.put("fieldName", fieldName);
			map.put("lazyType", StringUtils.equalsIgnoreCase(componentType, "info") ? infoType : componentType);
			list.add(map);
		}
	}

	public String genListViewCode(String pk, BaseInfoDto bModel, List<QueryDataDto> queryModel, ColDataDto colModel, List<TotalDataDto> totalData, List<Map<String, Object>> formDataList) {

		StringBuilder sb = new StringBuilder();

		boolean isWorkflow = bModel.getIsWorkflowForm();

		sb.append("<template>\r\n");
		sb.append("    <div class=\"main-container\"  :class=\"wrap?'main-wrap-container':'main-no-wrap-container'\" id=\"search-mixin-id\">\r\n");


		//是否有左边树结构
		if(colModel.getIsTree() > 0)
		{
			sb.append("        <main-fixed :title=\"treeTitle\">\r\n");
			sb.append("            <div slot=\"list\">\r\n");
			sb.append("                 <el-tree :data=\"treeData\" :props=\"defaultProps\" ref=\"").append(bModel.getName()).append("Tree\" node-key=\"").append(MapUtils.getString(colModel.getTreeForm(), "treefieldId")).append("\"\r\n");
			sb.append("                                        :default-expand-all=\"true\"  @node-click=\"handleNodeClick\">\r\n");


			Map<String, Object> treeForm = colModel.getTreeForm();;
			// 如果有父级图标
			if(StringUtil.isNotBlank(MapUtil.getStr(treeForm,"treeParentIcon"))){
				sb.append("             <span class=\"custom-tree-node\" slot-scope=\"{ data }\">\r\n");
				sb.append("                 <template v-if=\"data[defaultProps.children]&&data[defaultProps.children].length>0\">\r\n");
				sb.append("                     <i class=\"").append(treeForm.get(FormConstants.TREEPARENTICON)).append("\"></i>\r\n");
				sb.append("                     <span>{{ data[defaultProps.label]}}</span>\r\n");
				sb.append("                 </template>\r\n");

				sb.append("                 <template v-else>\r\n");
				sb.append("                     <i class=\"").append(treeForm.get(FormConstants.TREECHILDICON)).append("\"></i>\r\n");
				sb.append("                     <span>{{ data[defaultProps.label]}}</span>\r\n");
				sb.append("                </template>\r\n");
				sb.append("             </span>\r\n");

			}

			sb.append("             </el-tree>\r\n");
			sb.append("            </div>\r\n");
			sb.append("        </main-fixed>\r\n");
		}


		//-----------------------------搜索开始--------------------------------
		if(colModel.getIsTree() > 0)
		{
			sb.append("    <main-content :title=\"contentTitle\" :paddingLeft=\"210\">\r\n");
		}
		else
		{
			sb.append("    <main-content :title=\"contentTitle\" >\r\n");
		}


		StringBuilder searchString = new StringBuilder();



		sb.append("        <div slot=\"search\"  v-if=\"showSearchBox\">\r\n");
		sb.append("          <SearchBox \r\n");
		sb.append("            v-if=\"showSearchBox\"\r\n");
		sb.append("            :searchParamsList=\"searchParamsList\" \r\n");
		sb.append("            :searchParam.sync=\"searchParam\" \r\n");
		sb.append("            @searchBoxParams=\"searchClick\" \r\n");
		sb.append("            @searchReset=\"searchReset\" \r\n");
		sb.append("            ></SearchBox> \r\n");
		sb.append("        </div>\r\n");

		for (QueryDataDto item : queryModel) {
			//判断是否启用  不启用就不用添加
			if (item.getIsDate()){
				searchString.append("                       	{ \r\n");
				searchString.append("                       		name: '").append(item.getName()).append("', \r\n");
				searchString.append("                       		DateField: '").append(item.getDateField()).append("', \r\n");
				searchString.append("                       		field: '").append(item.getField()).append("', \r\n");

				Map<String, Object> fieldConfig = null;
				Map<String, Object> form = null;
				for (Map<String, Object> formData : formDataList) {

					Map<String, Object> config = MapUtils.getMap(formData, FormConstants.CONFIG);
					Map<String, Object> tabsMap = MapUtils.getMap(config, "childrenObj");

					//如果是tab组件
					if (tabsMap != null) {
						//tab组件就遍历tab下得所有子组件
						for (Object obj : tabsMap.values()) {
							List<Map<String, Object>> tabFieldList = (List<Map<String, Object>>) obj;
							for (Map<String, Object> tabField : tabFieldList) {
								Map<String, Object> tabFieldConfig = MapUtils.getMap(tabField, FormConstants.CONFIG);
								if (StringUtil.equalsIgnoreCase(item.getField(), MapUtils.getString(tabFieldConfig, FormConstants.BIND_TABLE_FIELD))) {
									fieldConfig = tabFieldConfig;
									form = tabField;
									break;
								}
							}
						}
					} else {
						if (StringUtil.equalsIgnoreCase(item.getField(), MapUtils.getString(config, FormConstants.BIND_TABLE_FIELD))) {
							fieldConfig = config;
							form = formData;
							break;
						}
					}
				}
				searchString.append("                       		tag: '").append(MapUtils.getString(fieldConfig, FormConstants.TAG,"el-input")).append("', \r\n");
				searchString.append("                       		avueType: '").append(MapUtils.getString(fieldConfig, FormConstants.FORM_COMPONENT_TYPE)).append("', \r\n");
				searchString.append("                       		lgmark: '").append(MapUtils.getString(fieldConfig, FormConstants.LGMARK,"")).append("', \r\n");
				// 如果是数据字典
				String dataType = MapUtils.getString(fieldConfig, FormConstants.FIELD_DATA_TYPE);
				if(StringUtil.equals(dataType,FormConstants.KEY_OF_FIELD_DATA_ITEM_CODE)){
					searchString.append("                       		dataType: '").append(dataType).append("', \r\n");
					searchString.append("                       		dataItem: '").append(MapUtils.getString(fieldConfig, FormConstants.KEY_OF_FIELD_DATA_ITEM_CODE)).append("', \r\n");
				}

				//API数据来源
				if (StringUtil.equals(dataType, FormConstants.KEY_OF_FIELD_DATE_API)) {
					searchString.append("dataType: '" + dataType + "',\r\n");
					searchString.append("apiConfig: " + JSONObject.toJSONString(fieldConfig.get("apiConfig")) + ",\r\n");
				}

				// 如果是数据源
				if(StringUtil.equals(dataType,FormConstants.KEY_OF_FIELD_DATA_SOURCE_ID)){
					searchString.append("                       		dataType: '").append(dataType).append("', \r\n");
					searchString.append("                       		dataSource: '").append(MapUtils.getString(fieldConfig, FormConstants.KEY_OF_FIELD_DATA_SOURCE_ID)).append("', \r\n");
					searchString.append("                       		saveField: '").append(MapUtils.getString(fieldConfig, FormConstants.KEY_OF_DATA_SOURCE_SAVE_FIELD)).append("', \r\n");
					searchString.append("                       		showField: '").append(MapUtils.getString(fieldConfig, FormConstants.KEY_OF_DATA_SOURCE_SHOW_FIELD)).append("', \r\n");
				}

				// 如果是信息体
				if(Boolean.TRUE.equals(MapUtils.getBoolean(form, FormConstants.ORG)) && StringUtil.isNotBlank(MapUtils.getString(form, FormConstants.FIELD_TYPE_OF_INFO_TYPE))){
					searchString.append("                       		__organize__: true, \r\n");
					searchString.append("                       		__info__: true, \r\n");
					searchString.append("                       		__type__: '").append(MapUtils.getString(form, FormConstants.FIELD_TYPE)).append("', \r\n");
					searchString.append("                       		infoType: '").append(MapUtils.getString(form, FormConstants.FIELD_TYPE_OF_INFO_TYPE)).append("', \r\n");
				}

				// 如果是公司组件
				if(StringUtil.equals(MapUtils.getString(form, FormConstants.FIELD_TYPE),FormConstants.FIELD_INFO_TYPE_OF_COMPANY)){
					searchString.append("                       		__organize__: true, \r\n");
					searchString.append("                       		__info__: false, \r\n");
					searchString.append("                       		__type__: '").append(MapUtils.getString(form, FormConstants.FIELD_TYPE)).append("', \r\n");
				}

				// 如果是人员组件
				if(StringUtil.equals(MapUtils.getString(form, FormConstants.FIELD_TYPE),FormConstants.FIELD_INFO_TYPE_OF_USER)){
					searchString.append("                       		__organize__: true, \r\n");
					searchString.append("                       		__info__: false, \r\n");
					searchString.append("                       		__type__: '").append(MapUtils.getString(form, FormConstants.FIELD_TYPE)).append("', \r\n");
				}

				// 如果是部门组件
				if(StringUtil.equals(MapUtils.getString(form, FormConstants.FIELD_TYPE),FormConstants.FIELD_INFO_TYPE_OF_DEPARTMENT)){
					searchString.append("                       		__organize__: true, \r\n");
					searchString.append("                       		__info__: false, \r\n");
					searchString.append("                       		__type__: '").append(MapUtils.getString(form, FormConstants.FIELD_TYPE)).append("', \r\n");
				}


				// 如果是级联组件
				if(StringUtil.equals(MapUtils.getString(fieldConfig, FormConstants.TAG),"xjr-cascader")){
					searchString.append("                       		settings: ").append(JSON.toJSONString(MapUtils.getObject(fieldConfig, "settings"))).append(", \r\n");
					searchString.append("                       		checkStrictly: " + MapUtils.getString(form, "checkStrictly", "false") + ",\r\n");
				}

				// 如果是时间组件
				String avueType = MapUtils.getString(fieldConfig, "avueType");
				String format = MapUtils.getString(form, "format");
				String string = MapUtils.getString(form, "value-format");
				if (StringUtil.equalsIgnoreCase(avueType, "time")) {
					searchString.append("                       		\"format\": \"" + format + "\",\r\n");
					searchString.append("                       		\"value-format\": \"" + string + "\",\r\n");
				}

				// 如果是日期组件
				if (StringUtil.equalsIgnoreCase(avueType, "datetime")) {
					searchString.append("                       		\"type\": \"" + MapUtils.getString(form, "type") + "\",\r\n");
					searchString.append("                       		\"format\": \"" + format + "\",\r\n");
					searchString.append("                       		\"value-format\": \"" + string + "\",\r\n");
				}

				//财务组件处理
				if (MapUtils.getBoolean(fieldConfig, "isFinance", false)) {
					searchString.append("                       		isFinance: true,\r\n");
				}

				// 级联组件
				if (StringUtils.equalsIgnoreCase(avueType, "cascader")) {
					searchString.append("                       		'show-all-levels': " + MapUtils.getBoolean(form, "show-all-levels", false) + ",\r\n");
				}


				searchString.append("                       	}, \r\n");


			}
		}













		//--------------------------------查询结束   列表开始----------------------------
		sb.append("        <div slot=\"table\">\r\n");
		sb.append("        <!-- 在此处放置表格内容 -->\r\n");


		String batchDeleteOptionStr = StringPool.EMPTY;
		String batchDeletCrudStr = StringPool.EMPTY;
		String batchDeleteMethodStr = StringPool.EMPTY;
		//判断是否有批量删除按钮
		if (colModel.getButtonList().stream().anyMatch(x -> MapUtils.getBoolean(x, "checked") && StringUtil.equalsIgnoreCase(MapUtils.getString(x, "val"), "batchDelete")))
		{
			batchDeleteOptionStr = "                       selection: true,\r\n";
			batchDeletCrudStr = "@selection-change=\"selectionChange\"";

			batchDeleteMethodStr += "                           selectionChange(list){\r\n";
			batchDeleteMethodStr += "                             this.ids = list.map((x) => x." + pk + ").join(',');\r\n";
			batchDeleteMethodStr += "                           },\r\n";

			batchDeleteMethodStr += "                           batchDelete() {\r\n";


			batchDeleteMethodStr += "                            if (!this.ids || this.ids.split(\",\").length === 0) {\r\n";
			batchDeleteMethodStr += "                                 this.$message.error(this.$t(\"deletePrompt.noSelected\"));\r\n";
			batchDeleteMethodStr += "                                 return;\r\n";
			batchDeleteMethodStr += "                           }\r\n";

			batchDeleteMethodStr += "                             this.$confirm(this.$t(\"deletePrompt.promptContent\"), this.$t(\"tip\"), {\r\n";
			batchDeleteMethodStr += "                               confirmButtonText: this.$t(\"buttonModule.modalSureBtn\"),\r\n";
			batchDeleteMethodStr += "                               cancelButtonText: this.$t(\"editorModule.cancel\"),\r\n";
			batchDeleteMethodStr += "                               type: \"warning\",\r\n";
			batchDeleteMethodStr += "                             }).then(() => {\r\n";
			batchDeleteMethodStr += "                               request({\r\n";
			batchDeleteMethodStr += "                                 url: baseUrl + \"/" + bModel.getName().toLowerCase() + "/\" + this.ids,\r\n";
			batchDeleteMethodStr += "                                 method: \"delete\",\r\n";
			batchDeleteMethodStr += "                               }).then((res) => {\r\n";
			batchDeleteMethodStr += "                                 this.getListData();\r\n";
			batchDeleteMethodStr += "                                 this.$notify({\r\n";
			batchDeleteMethodStr += "                                   title: this.$t(\"Notice.hintSuccess\"),\r\n";
			batchDeleteMethodStr += "                                   message: this.$t(\"deletePrompt.successDeleted\"),\r\n";
			batchDeleteMethodStr += "                                   type: \"success\",\r\n";
			batchDeleteMethodStr += "                                 });\r\n";
			batchDeleteMethodStr += "                               });\r\n";
			batchDeleteMethodStr += "                             });\r\n";
			batchDeleteMethodStr += "                           },\r\n";
		}

		if(StringUtil.equalsIgnoreCase(colModel.getIsPage(), "1"))
		{
			sb.append("            <avue-crud ref=\"" + bModel.getName() + "Table\" :data=\"listData\" :showColumn=\"showColumn\" :isSaveColumns=\"true\" "+ batchDeletCrudStr + " id=\"printTable\" :option=\"option\" stripe :page.sync=\"page\"\r\n");

			sb.append("                       @on-load=\"onPageLoad\"\r\n");
			sb.append("                       @row-dblclick=\"handleRowDBLClick\"\r\n");
			sb.append("                       @sort-change=\"sortChange\" \r\n");
			sb.append("                       @current-row-change=\"handleCurrentRowChange\" >\r\n");
		}
		else
		{
			sb.append("            <avue-crud ref=\"" + bModel.getName() + "Table\" :data=\"listData\" :showColumn=\"showColumn\" :isSaveColumns=\"true\" " + batchDeletCrudStr + "  id=\"printTable\" :option=\"option\" stripe \r\n");

			sb.append("                       @row-dblclick=\"handleRowDBLClick\"\r\n");
			sb.append("                       @sort-change=\"sortChange\"\r\n");
			sb.append("                       @current-row-change=\"handleCurrentRowChange\" >\r\n");
		}

		List<Map<String, Object>> columnList = colModel.getColumnList();
		boolean existChineseCapital = false;
		if (CollectionUtil.isNotEmpty(columnList)) {
			for (Map<String, Object> column : columnList) {
				String fieldName = MapUtils.getString(column, "bindColumn");
				Map<String, Object> fieldConfig = findFieldConfig(formDataList, fieldName);
				Map<String, Object> config = MapUtils.getMap(fieldConfig, FormConstants.CONFIG);
				if (StringUtil.equalsIgnoreCase(MapUtils.getString(config, "avueType"), "switch")) {
					sb.append("                <template slot=\"" + fieldName + "\" slot-scope=\"scope\">\r\n");
					sb.append("                	<el-switch\r\n");
					sb.append("                			v-model=\"scope.row." + fieldName + "\"\r\n");
					sb.append("                			active-color=\"" + MapUtils.getString(fieldConfig, "active-color", "#13ce66") + "\"\r\n");
					sb.append("                			inactive-color=\"" + MapUtils.getString(fieldConfig, "inactive-color", "#a29e9e") + "\"\r\n");
					sb.append("                			:active-value=\"" + MapUtils.getString(fieldConfig, "active-value") + "\"\r\n");
					sb.append("                			:inactive-value=\"" + MapUtils.getString(fieldConfig, "inactive-value") + "\"\r\n");
					sb.append("                			disabled>\r\n");
					sb.append("                	</el-switch>\r\n");
					sb.append("                </template>\r\n");
				} else if (MapUtils.getBoolean(fieldConfig, "isCapitalized", false)) {
					sb.append("                <template slot=\"" + fieldName + "\" slot-scope=\"scope\">\r\n");
					sb.append("                		{{getConvertToChineseCapital(scope.row." + fieldName + ")}}\r\n");
					sb.append("                </template>\r\n");
					existChineseCapital = true;
				}
			}
		}

		sb.append("                <template slot-scope=\"scope\" slot=\"menu\">\r\n");
		String lowerServiceName = StringUtils.lowerCase(bModel.getName());
		if(isWorkflow){
			sb.append("		  			   <template v-if=\"scope.row.flowStatus&&scope.row.flowStatus==2\">\r\n");
			sb.append("						  <span v-if=\"hasBtns('" + lowerServiceName + ":createFormFlow') && hasButtonPermission('" + lowerServiceName + ":createFormFlow')\" class=\"form-span-button\">{{$t(\"workFlow.WFChange.approval\")}}</span>\r\n");
			sb.append("						  <el-button type=\"opr-primary\" size=\"mini\"  icon=\"el-icon-view\"  v-if=\"hasBtns('" + lowerServiceName + ":view')&&hasButtonPermission('" + lowerServiceName + ":view')\" @click=\"viewForm(scope.row)\">{{$t(\"crud.viewBtn\")}}</el-button>\r\n");
			sb.append("		  		 	   </template>\r\n");
			sb.append("		  			   <template v-else-if=\"scope.row.flowStatus&&scope.row.flowStatus==3\">\r\n");
			sb.append("						  <span v-if=\"hasBtns('" + lowerServiceName + ":createFormFlow') && hasButtonPermission('" + lowerServiceName + ":createFormFlow')\" class=\"form-span-button\">{{$t(\"forme.editModal.approvalComplete\")}}</span>\r\n");
			sb.append("						  <el-button type=\"opr-primary\" size=\"mini\"  icon=\"el-icon-view\"  v-if=\"hasBtns('" + lowerServiceName + ":view')&&hasButtonPermission('" + lowerServiceName + ":view')\" @click.stop=\"viewForm(scope.row)\">{{$t(\"crud.viewBtn\")}}</el-button>\r\n");
			sb.append("						  <el-button type=\"opr-primary\" size=\"mini\"  icon=\"el-icon-edit\" v-if=\"hasBtns('" + lowerServiceName + ":modify')&&hasButtonPermission('" + lowerServiceName + ":modify')\" @click.stop=\"editForm(scope.row)\">{{$t(\"crud.editBtn\")}}</el-button>\r\n");
			sb.append("						  <el-button type=\"opr-primary\" size=\"mini\"  icon=\"el-icon-delete\" v-if=\"hasBtns('" + lowerServiceName + ":delete')&&hasButtonPermission('" + lowerServiceName + ":delete')\" @click.stop=\"deleteForm(scope.row)\">{{$t(\"crud.delBtn\")}}</el-button>\r\n");
			sb.append("		  			   </template>\r\n");
			sb.append("		  			   <template v-else>\r\n");
			sb.append("			  			  <el-button type=\"opr-primary\" size=\"mini\" icon=\"el-icon-guide\" v-if=\"scope.row.flowStatus&&scope.row.flowStatus==1&&hasBtns('" + lowerServiceName + ":createFormFlow') && hasButtonPermission('" + lowerServiceName + ":createFormFlow')\" @click=\"CreateFormFlow(scope.row)\">{{$t(\"forme.editModal.initiateApproval\")}}</el-button>\r\n");
			sb.append("			  			  <el-button type=\"opr-primary\" size=\"mini\" icon=\"el-icon-guide\" v-if=\"hasBtns('" + lowerServiceName + ":createDesignFlow') && hasButtonPermission('" + lowerServiceName + ":createDesignFlow')\" @click=\"CreateDesignFlow(scope.row)\">{{$t(\"forme.editModal.createFormFlowBtn\")}}</el-button>\r\n");
			sb.append("			  			  <el-button type=\"opr-primary\" size=\"mini\"  icon=\"el-icon-view\"  v-if=\"hasBtns('" + lowerServiceName + ":view')&&hasButtonPermission('" + lowerServiceName + ":view')\" @click=\"viewForm(scope.row)\">{{$t(\"crud.viewBtn\")}}</el-button>\r\n");
			sb.append("			  			  <el-button type=\"opr-primary\" size=\"mini\"  icon=\"el-icon-edit\" v-if=\"hasBtns('" + lowerServiceName + ":modify')&&hasButtonPermission('" + lowerServiceName + ":modify')\" @click=\"editForm(scope.row)\">{{$t(\"crud.editBtn\")}}</el-button>\r\n");
			sb.append("			  			  <el-button type=\"opr-primary\" size=\"mini\"  icon=\"el-icon-delete\" v-if=\"hasBtns('" + lowerServiceName + ":delete')&&hasButtonPermission('" + lowerServiceName + ":delete')\" @click=\"deleteForm(scope.row)\">{{$t(\"crud.delBtn\")}}</el-button>\r\n");
			sb.append("					   </template>\r\n");
		} else {
			sb.append("                    <el-button type=\"opr-primary\" size=\"mini\"  icon=\"el-icon-view\"  v-if=\"hasBtns('" + lowerServiceName + ":view')&&hasButtonPermission('" + lowerServiceName + ":view')\" @click=\"viewForm(scope.row)\">{{$t(\"crud.viewBtn\")}}</el-button>\r\n");
			sb.append("                    <el-button type=\"opr-primary\" size=\"mini\"  icon=\"el-icon-edit\" v-if=\"hasBtns('" + lowerServiceName + ":modify')&&hasButtonPermission('" + lowerServiceName + ":modify')\" @click=\"editForm(scope.row)\">{{$t(\"crud.editBtn\")}}</el-button>\r\n");
			sb.append("                    <el-button type=\"opr-primary\" size=\"mini\"  icon=\"el-icon-delete\" v-if=\"hasBtns('" + lowerServiceName + ":delete')&&hasButtonPermission('" + lowerServiceName + ":delete')\" @click=\"deleteForm(scope.row)\">{{$t(\"crud.delBtn\")}}</el-button>\r\n");
		}

		sb.append("                </template>\r\n");


		//生成按钮
		sb.append("                 <template slot=\"menuLeft\">\r\n");
		if (colModel.getButtonList().size() > 0)
		{
			for(Map<String, Object> btn : colModel.getButtonList())
			{
				if(MapUtils.getBoolean(btn, "checked"))
				{
					switch(MapUtils.getString(btn, "val"))
					{
						case "add":
							sb.append("                     <el-button type=\"primary\"  v-if=\"hasButtonPermission('" + lowerServiceName + ":" + MapUtils.getString(btn, "val") + "')\" icon=\"" + MapUtils.getString(btn, "icon") + "\" size=\"small\" @click=\"openForm()\">{{$t(\"crud.addBtn\")}}</el-button>\r\n");
							break;
						case "batchDelete":
							sb.append("                     <el-button type=\"primary\"  v-if=\"hasButtonPermission('" + lowerServiceName + ":" + MapUtils.getString(btn, "val") + "')\" icon=\"" + MapUtils.getString(btn, "icon") + "\" size=\"small\" @click=\"batchDelete()\">{{$t(\"forme.editModal.batchDeletionBtn\")}}</el-button>\r\n");
							break;
						case "print":
							sb.append("                     <el-button type=\"primary\"  v-if=\"hasButtonPermission('" + lowerServiceName + ":" + MapUtils.getString(btn, "val") + "')\" icon=\"" + MapUtils.getString(btn, "icon") + "\" size=\"small\" @click=\"printForm\">{{$t(\"editorModule.print\")}}</el-button>\r\n");
							break;
						case "import":
							sb.append("                     <el-button type=\"primary\"  v-if=\"hasButtonPermission('" + lowerServiceName + ":" + MapUtils.getString(btn, "val") + "')\" icon=\"" + MapUtils.getString(btn, "icon") + "\" size=\"small\" @click=\"excelDialog = true\">{{$t(\"forme.editModal.quickImportBtn\")}}</el-button>\r\n");
							break;
						case "export":
							sb.append("                     <el-button type=\"primary\"  v-if=\"hasButtonPermission('" + lowerServiceName + ":" + MapUtils.getString(btn, "val") + "')\" icon=\"" + MapUtils.getString(btn, "icon") + "\" size=\"small\" @click=\"tableExport()\">{{$t(\"forme.editModal.quickExportBtn\")}}</el-button>\r\n");
							break;
						case "modify" :
						case "delete" :
						case "createDesignFlow" :
						case "createFormFlow" :
						case "refresh" :
						case "view" :
							break;
						default:
							sb.append("                     <el-button type=\"primary\"  v-if=\"hasButtonPermission('" + lowerServiceName + ":" + MapUtils.getString(btn, "val") + "')\" icon=\"" + MapUtils.getString(btn, "icon") + "\" size=\"small\">" + MapUtils.getString(btn, "name") + "</el-button>\r\n");
							break;
					}
				}
			}
		}
		sb.append("                </template>\r\n");


		sb.append("            </avue-crud>\r\n");

		//--------------------------------表单----------------------------

		switch(StringUtils.defaultIfEmpty(bModel.getFormSize(), StringPool.EMPTY))
		{
			case "fullscreen": //全屏
				sb.append("            <el-dialog title=\"表单\"  v-dialogDrag :append-to-body=\"true\" :fullscreen=\"true\" :visible.sync=\"flag\"  :class=\"isWorkflowForm ? 'work-form-dialog' : ''\" :show-close=\"!isWorkflowForm\" >\r\n");
				sb.append("                <"+bModel.getName()+"Form ");
				if(isWorkflow){
					sb.append("ref=\"xtForm\"  ");
				}
				sb.append("v-if=\"flag\"  :isEdit=\"isEdit\" :disabled=\"disabled\" @onChange=\"dialogChange\" :keyValue=\"keyValue\"></" + bModel.getName() + "Form>\r\n");
				sb.append("            </el-dialog>\r\n");
				break;
			case "medium": //大
				sb.append("            <el-dialog title=\"表单\" :append-to-body=\"true\" width=\"65%\" :visible.sync=\"flag\" :class=\"isWorkflowForm ? 'work-form-dialog' : ''\" :show-close=\"!isWorkflowForm\">\r\n");
				sb.append("                <"+bModel.getName()+"Form ");
				if(isWorkflow){
					sb.append("ref=\"xtForm\"  ");
				}
				sb.append("v-if=\"flag\"  :isEdit=\"isEdit\" :disabled=\"disabled\" @onChange=\"dialogChange\" :keyValue=\"keyValue\"></" + bModel.getName() + "Form>\r\n");
				sb.append("            </el-dialog>\r\n");
				break;
			case "small": //中
				sb.append("            <el-dialog title=\"表单\" :append-to-body=\"true\" width=\"50%\" :visible.sync=\"flag\" :class=\"isWorkflowForm ? 'work-form-dialog' : ''\" :show-close=\"!isWorkflowForm\">\r\n");
				sb.append("                <"+bModel.getName()+"Form ");
				if(isWorkflow){
					sb.append("ref=\"xtForm\"  ");
				}
				sb.append("v-if=\"flag\"  :isEdit=\"isEdit\" :disabled=\"disabled\" @onChange=\"dialogChange\" :keyValue=\"keyValue\"></" + bModel.getName() + "Form>\r\n");
				sb.append("            </el-dialog>\r\n");
				break;
			case "mini": //小
				sb.append("            <el-dialog title=\"表单\" :append-to-body=\"true\" width=\"35%\" :visible.sync=\"flag\" :class=\"isWorkflowForm ? 'work-form-dialog' : ''\" :show-close=\"!isWorkflowForm\">\r\n");
				sb.append("                <"+bModel.getName()+"Form ");
				if(isWorkflow){
					sb.append("ref=\"xtForm\"  ");
				}
				sb.append("v-if=\"flag\"  :isEdit=\"isEdit\" :disabled=\"disabled\" @onChange=\"dialogChange\" :keyValue=\"keyValue\"></" + bModel.getName() + "Form>\r\n");
				sb.append("            </el-dialog>\r\n");
				break;
			default:  //默认全屏
				sb.append("            <el-dialog title=\"表单\" :append-to-body=\"true\" :fullscreen=\"true\" :visible.sync=\"flag\" :class=\"isWorkflowForm ? 'work-form-dialog' : ''\" :show-close=\"!isWorkflowForm\">\r\n");
				sb.append("                <"+bModel.getName()+"Form ");
				if(isWorkflow){
					sb.append("ref=\"xtForm\"  ");
				}
				sb.append("v-if=\"flag\"  :isEdit=\"isEdit\" :disabled=\"disabled\" @onChange=\"dialogChange\" :keyValue=\"keyValue\"></" + bModel.getName() + "Form>\r\n");
				sb.append("            </el-dialog>\r\n");
				break;

		}

		//--------------------------------表单结束----------------------------

		//--------------------------------导入----------------------------
		//如果有导出按钮
		if (colModel.getButtonList().stream().anyMatch(x -> MapUtils.getBoolean(x, "checked") && StringUtil.equalsIgnoreCase(MapUtils.getString(x, "val"), "import")))
		{
			sb.append("      <el-dialog title=\"快速导入\" width=\"30%\" :append-to-body=\"true\" :visible.sync=\"excelDialog\">\r\n");
			sb.append("        <el-upload\r\n");
			sb.append("           class=\"upload-demo\"\r\n");
			sb.append("           ref=\"upload\"\r\n");
			sb.append("           :data=\"uploadData\"\r\n");
			sb.append("           :before-upload=\"beforeUpload\"\r\n");
			sb.append("           :on-success=\"successUpload\"\r\n");
			sb.append("           :show-file-list=\"true\"\r\n");
			sb.append("           drag\r\n");
			sb.append("           :headers=\"headers\"\r\n");
			sb.append("           accept=\".xlsx,.xls\"\r\n");
			sb.append("           :action=\"baseUrl + '/" + bModel.getName().toLowerCase() + "/import'\">\r\n");

			sb.append("           <i class=\"el-icon-upload\"></i>\r\n");
			sb.append("           <div class=\"el-upload__text\">将文件拖到此处，或<em>点击上传</em></div>\r\n");
			sb.append("           <div class=\"el-upload__tip\" slot=\"tip\">只能上传Excel文件，且不超过1G</div>\r\n");
			sb.append("        </el-upload>\r\n");


			sb.append("         <el-row type=\"flex\">\r\n");
			sb.append("           <el-col>\r\n");
			sb.append("           </el-col>\r\n");
			sb.append("           <el-col style=\"text-align:right;\">\r\n");
			sb.append("            <p></p>\r\n");
			sb.append("            <el-button icon=\"el-icon-download\" @click=\"download\"> 下载模板</el-button>\r\n");
			sb.append("           </el-col>\r\n");
			sb.append("         </el-row>\r\n");
			sb.append("     </el-dialog>\r\n");
		}
		//--------------------------------导入结束----------------------------


		sb.append("        </div>\r\n");
		//--------------------------------列表结束----------------------------
		sb.append("    </main-content>\r\n");
		if(isWorkflow){
			sb.append("    <createFlow v-if=\"isCreateFlow\" formType=\"2\" rowPrimaryKey=\"" + pk + "\" :UrlAddress=\"this.$options.name\" :createFlowType=\"createFlowType\" :row=\"scopeRow\" :scheme=\"scheme\" @closedCreateFlow=\"closedCreateFlow\"></createFlow>\r\n");
		}




		sb.append("    </div>\r\n");
		sb.append("</template>\r\n");


		//--------------------------------JS开始----------------------------
		sb.append("<script>\r\n");
        if(isWorkflow){
        	sb.append("      import createFlow from '@/components/formInitiationProcess/createFlow';\r\n");
        	sb.append("      import schemeMixins from '@/components/formInitiationProcess/schemeMixins';\r\n");
		}
		if (queryModel.size() > 0)
		{
			sb.append("     import MainFixed from \"@/page/main/MainFixed\";\r\n");
		}
		sb.append("      import authorizeMixin from \"@/mixins/authorize\";\r\n");
		sb.append("      import tableOptionMixin from \"@/mixins/tableOption\"; //table 高度计算\r\n");
		sb.append("      import tableSearchMixin from \"@/mixins/tableSearch\"; //table 搜索 \r\n");
		sb.append("      import displayColumnsMixin from \"@/mixins/displayColumns\"; //表格展示列显隐保存 \r\n");



		sb.append("     import MainContent from \"@/page/main/MainContent\";\r\n");

		sb.append("      import request from '@/router/axios';\r\n");
		sb.append("      import { baseUrl } from '@/config/env';\r\n");
		sb.append("      import { getOrder } from '@/util/util';\r\n");

		////如果有导出按钮
		//if (colModel.Btns.Exists(x=>x.Checked && x.Val == "export"))
		//{
		//    sb.append("      import { saveAs } from \"file-saver\";\r\n");
		//    sb.append("      import XLSX from \"xlsx\";\r\n");
		//}


		//引入表单页
		sb.append("      import " + bModel.getName() + "Form from './" + bModel.getName() + "Form';\r\n");

		if (existChineseCapital) {
			sb.append("      import {convertToChineseCapital} from '@/components/codeParser/util.js';\r\n");
		}

		sb.append("     export default {\r\n");
		sb.append("         name: \"" + bModel.getName() + "\",\r\n");
		sb.append("         mixins: [authorizeMixin,tableOptionMixin,tableSearchMixin,displayColumnsMixin");
		if(isWorkflow){
			sb.append(",schemeMixins");
		}
		sb.append("],\r\n");
		sb.append("         components: { MainContent, " + bModel.getName() + "Form");
		if(isWorkflow){
			sb.append(",createFlow");
		}
		if (queryModel.size() > 0)
		{
			sb.append(",MainFixed");
		}
		sb.append(" },\r\n");
		sb.append("         data() {\r\n");
		sb.append("              return {\r\n");

//		sb.append("				 	  computedHeight:50,\r\n");
		sb.append("				 	  btns:[\r\n");
		if (colModel.getButtonList().size() > 0) {
			int index = 0;
			for (Map<String, Object> btn : colModel.getButtonList()) {
				if (!MapUtils.getBoolean(btn, "checked")) {
					continue;
				}
				if (index > 0) {
					sb.append(",\r\n");
				}
				sb.append("				 	     '" + lowerServiceName + ":" + btn.get("val") + "'");
				index++;
			}
		}
		sb.append("\r\n");
		sb.append("                   ],\r\n");

//		sb.append("                   contentTitle: '" + bModel.getDescribe() + "列表',\r\n");

		if (colModel.getIsTree() > 0)
		{

			sb.append("                   treeTitle: '" + MapUtils.getString(colModel.getTreeForm(), "treeTitleName") + "',\r\n");
			sb.append("                   treeData: [],\r\n");
			sb.append("                   treeSelect: '',//左边树所选\r\n");
		}
		if(StringUtil.equalsIgnoreCase(colModel.getIsPage(), "1"))
		{
			sb.append("                   page: {\r\n");
			sb.append("                       pageSize: " + colModel.getPageSize() + ",\r\n");
			sb.append("                       total: 0,\r\n");
			sb.append("                       currentPage: 1,\r\n");
			sb.append("                       layout: \"total, prev, pager, next, jumper\"\r\n");
			sb.append("                   },\r\n");
		}
		if(colModel.getButtonList().stream().anyMatch(x -> MapUtils.getBoolean(x, "checked") && StringUtil.equalsIgnoreCase(MapUtils.getString(x, "val"), "batchDelete")))
		sb.append("                   ids: '',\r\n");


		sb.append("                   listData: [],\r\n");
		sb.append("                   keyValue: '',\r\n");

		sb.append("                   flag:false,\r\n");
//		sb.append("                   computedHeight:0,\r\n");


		sb.append("                   isEdit: true, // 查看-不显示按钮,\r\n");
		sb.append("                   disabled: false, // 查看-禁用input,\r\n");
		sb.append("                   isWorkflowForm:false,//默认值 false\r\n");
		SortDataDto sortDataDto = colModel.getSortDataDto();
		sb.append("                   defaultOrderfield:'" + (sortDataDto.getUseDefaultSort() ? StringPool.EMPTY : sortDataDto.getSortField()) + "',//默认排序字段\r\n");
		sb.append("                   defaultOrder:'" + (sortDataDto.getUseDefaultSort() ? StringPool.EMPTY : sortDataDto.getOrder()) + "',//默认排序\r\n");

		sb.append("                   searchParam: {");
		sb.append("},\r\n");


		sb.append("                   defaultProps: {\r\n");
		sb.append("                       children: 'children',\r\n");
		sb.append("                       label: '" + MapUtils.getString(colModel.getTreeForm(), "treefieldShow") + "'\r\n");
		sb.append("                   },\r\n");

		//如果有导出按钮
		if (colModel.getButtonList().stream().anyMatch(x -> MapUtils.getBoolean(x, "checked") && StringUtil.equalsIgnoreCase(MapUtils.getString(x, "val"), "import")))
		{
			sb.append("                    uploadData: {  F_ModuleId: '' },\r\n");
			sb.append("                    headers: {   },\r\n");
			sb.append("                    excelDialog: false,\r\n");
		}



		sb.append("                   option:{\r\n");
		sb.append("                       rowKey:'"+ pk + "',\r\n");
		sb.append("                       highlightCurrentRow: true,\r\n");
		sb.append("                       stripe: true,\r\n");
		sb.append("                       addBtn: false,\r\n");
		sb.append("                       tip:false,\r\n");
		sb.append("                       menuWidth:");
		if(isWorkflow){
			sb.append(" 320,\r\n");
		}else {
			sb.append(" 230,\r\n");
		}
//		sb.append("                       maxHeight: 550,\r\n");
		sb.append("                       border: true,\r\n");

		//是否分页
		if(StringUtil.equalsIgnoreCase(colModel.getIsPage(), "1"))
		{
			sb.append("                       page: true,\r\n");
		}
		else
		{
			sb.append("                       page: false,\r\n");
		}

		//是否有合计配置
		if(totalData.size() > 0)
		{
			sb.append("                       showSummary: false,\r\n");
			sb.append("                       sumColumnList: [\r\n");
			for(TotalDataDto item : totalData)
			{
				sb.append("                         {\r\n");

				//如果有设置合计label
				if(!StringUtil.isEmpty(item.getLabel()))
				{
					sb.append("                            label : '" + item.getLabel() + ": ',\r\n");
				}
				sb.append("                            name : '" + item.getName() + "',\r\n");
				sb.append("                            type : '" + item.getType() + "',\r\n");

				sb.append("                         },\r\n");
			}
			sb.append("                       ],\r\n");
		}

		sb.append(batchDeleteOptionStr);
		sb.append("                       index: true,\r\n");
		sb.append("                       menu: false,\r\n");
		sb.append("                       indexLabel: this.$t('custmerForm.tableNumber'),\r\n");
		sb.append("                       align: 'center',\r\n");
		sb.append("                       menuAlign: 'left',\r\n");
		sb.append("                       delBtn: false,\r\n");
		sb.append("                       editBtn: false,\r\n");
		sb.append("                       column: [\r\n");


		for(Map<String, Object> item : columnList) {
			String column = MapUtils.getString(item, "bindColumn");
			Map<String, Object> fieldConfig = findFieldConfig(formDataList, column);
			String lgMark = MapUtils.getString(fieldConfig, "F_LgMarkCode");
			sb.append("                           {\r\n");
			sb.append("                               sortable: true,\r\n");
			sb.append("                               label: this.$t(\""+ (StringUtil.isEmpty(lgMark) ? item.get("fieldName") : lgMark) +"\"),\r\n");

			sb.append("                               prop: '"+item.get("bindColumn")+"',\r\n");//width
			sb.append("                               overHidden: true,\r\n");
			Map<String, Object> config = MapUtils.getMap(fieldConfig, FormConstants.CONFIG);
			if (StringUtil.equalsIgnoreCase(MapUtils.getString(config, "avueType"), "switch")
					|| MapUtils.getBoolean(fieldConfig, "isCapitalized", false)) {
				sb.append("                               slot: true,\r\n");
			}

			if(!StringUtil.isEmpty(item.get("width")))
			{
				sb.append("                               width: '" + item.get("width") + "'\r\n");
			}

			sb.append("                           },\r\n");
		}

		sb.append("                       ]\r\n");
		sb.append("                   }\r\n");



		sb.append("              }\r\n");




		sb.append("                   },\r\n");

		sb.append("                   created() {\r\n");

		sb.append("                       //是否有编辑 查看 删除 发起流程 发起临时流程权限 无则为操作列不显示\r\n");
		sb.append("                       let oprBtns = ['" + lowerServiceName + ":modify','" + lowerServiceName + ":view','" + lowerServiceName + ":delete','" + lowerServiceName + ":createFormFlow','" + lowerServiceName + ":createDesignFlow'];\r\n");
		sb.append("                       let intersection = this.btns.filter((v) => oprBtns.includes(v)); \r\n");
		sb.append("                       if(intersection.length>0){\r\n");
		sb.append("                       	this.option.menu =  true\r\n");
		sb.append("                       }else{\r\n");
		sb.append("                       	this.option.menu = false\r\n");
		sb.append("                       }\r\n");

		if(colModel.getIsTree() == 1) //如果是树结构  默认执行左边树的方法
		{
			sb.append("                       this.getTreeData()\r\n");
		}
		else//如果不是树结构  直接请求获取列表数据
		{
			//如果不分页 需要自己请求  如果分页 前端组件会帮忙发送请求
			if (!StringUtil.equalsIgnoreCase(colModel.getIsPage(), "1"))
				sb.append("                       this.getListData()\r\n");
		}

		sb.append("                       let querySearchData = [\r\n");
		sb.append(searchString).append("\r\n");
		sb.append("                       ]\r\n");
		sb.append("                       this.getSystemSearchList(querySearchData);\r\n");
//		sb.append("                       this.searchBtns  = this.btns.concat(oprBtns).filter((v) => this.btns.includes(v) && !oprBtns.includes(v));//搜索栏按钮\r\n");
		sb.append("                       if(this.btns.length>0){\r\n");
		sb.append("                       	let tempBtns =  this.btns.concat(oprBtns).filter((v) => this.btns.includes(v) && !oprBtns.includes(v));\r\n");
		sb.append("                       	if(tempBtns.length>0){\r\n");
		sb.append("                       		this.searchBtns  = [...new Set([...tempBtns])];\r\n");
		sb.append("                       	}\r\n");
		sb.append("                       }\r\n");




//		sb.append("                       /** 工作流  系统表单  相关方法 start*/\r\n");
//		sb.append("                       let self = this;\r\n");
//		sb.append("                       window.parent.openDialog = () => {\r\n");
//		sb.append("                         self.isWorkflowForm = true;\r\n");
//		sb.append("                         self.openForm();\r\n");
//		sb.append("                       };\r\n");
//		sb.append("                         /** 工作流 系统表单  相关方法 end */\r\n");


		//如果有导出按钮
		if (colModel.getButtonList().stream().anyMatch(x -> MapUtils.getBoolean(x, "checked") && StringUtil.equalsIgnoreCase(MapUtils.getString(x, "val"), "import")))
		{
			sb.append("                      const token = JSON.parse(localStorage.getItem('avue-token'))['content'];\r\n");
			sb.append("                      this.headers.Authorization = 'Bearer ' + token\r\n");
			sb.append("                       this.uploadData = { F_ModuleId: this.$route.meta.moduleid };\r\n");
		}

		sb.append("                   },\r\n");


		//------------------method start-----------------------
		sb.append("                   methods: {\r\n");
		if (existChineseCapital) {
			sb.append("                         getConvertToChineseCapital(num){\r\n");
			sb.append("                         	return convertToChineseCapital(num);\r\n");
			sb.append("                         },\r\n");
		}
		sb.append("                         handleRowDBLClick (row, event) {\r\n");
		sb.append("                         	if(this.hasBtns('" + lowerServiceName + ":modify')&&this.hasButtonPermission('" + lowerServiceName + ":modify')&&this.openDoubleClickEdit){\r\n");
		sb.append("                         		this.editForm(row)\r\n");
		sb.append("                         	}\r\n");
		sb.append("                         },\r\n");
		sb.append("                         handleCurrentRowChange(row){\r\n");
		sb.append("                         	this.$refs."+ bModel.getName() + "Table.toggleSelection([row]);\r\n");
		sb.append("                         },\r\n");
		sb.append("                         printForm() {\r\n");
		sb.append("                         	let element = window.document.getElementById(\"printTable\");\r\n");
		sb.append("                         	setTimeout(() => {\r\n");
		sb.append("                         	  html2canvas(element, {\r\n");
		sb.append("                         		backgroundColor: null,\r\n");
		sb.append("                         		useCORS: true,\r\n");
		sb.append("                         		windowHeight: document.body.scrollHeight\r\n");
		sb.append("                         	  }).then(canvas => {\r\n");
		sb.append("                         		const url = canvas.toDataURL();\r\n");
		sb.append("                         		this.printImg = url;\r\n");
		sb.append("                         		printJS({\r\n");
		sb.append("                         		  printable: url,\r\n");
		sb.append("                         		  type: \"image\",\r\n");
		sb.append("                         		  documentTitle: '打印',\r\n");
		sb.append("                         		  scanStyles: false,\r\n");
		sb.append("                         		  repeatTableHeader: false,\r\n");
		sb.append("                         		  header: null\r\n");
		sb.append("                         		});\r\n");
		sb.append("                          	  });\r\n");
		sb.append("                         	}, 1);\r\n");
		sb.append("                           },\r\n");
		//添加是设置按钮方法
		sb.append("                         hasBtns(encode){\r\n");
		sb.append("                         	return this.btns.includes(encode);\r\n");
		sb.append("                         },\r\n");

		//如果发布流程则添加
		if(isWorkflow){
			sb.append("                         /**发起流程 */\r\n");
			sb.append("                         CreateDesignFlow(val) {\r\n");
			sb.append("                            this.createFlowType = 0;\r\n");
			sb.append("                            this.scopeRow = val;\r\n");
			sb.append("                            this.changeSystemSchemeInfo();\r\n");
			sb.append("                         },\r\n");

			sb.append("                         CreateFormFlow(val) {\r\n");
			sb.append("                            this.createFlowType = 1;\r\n");
			sb.append("                            this.scopeRow = val;\r\n");
			sb.append("                            this.isCreateFlow = true;\r\n");
			sb.append("                         },\r\n");
		}

		//如果有导出按钮 新增导入按钮所需要方法
		if (colModel.getButtonList().stream().anyMatch(x -> MapUtils.getBoolean(x, "checked") && StringUtil.equalsIgnoreCase(MapUtils.getString(x, "val"), "import")))
		{
			sb.append("                         download(){\r\n");
			sb.append("                             request({\r\n");
			sb.append("                                 url: baseUrl + '/excel-import/download/' + this.$route.meta.moduleid,\r\n");
			sb.append("                                 method: 'get',\r\n");
			sb.append("                                 responseType: 'blob'\r\n");
			sb.append("                              }).then(res =>{                  \r\n");
			sb.append("                                    let url = window.URL.createObjectURL(new Blob([res.data],{type : \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\"}));\r\n");
			sb.append("                                    let link = document.createElement('a');\r\n");
			sb.append("                                    link.style.display = 'none';\r\n");
			sb.append("                                    link.href = url;\r\n");
			sb.append("                                    link.setAttribute('download', '" + bModel.getName() + ".xlsx');\r\n");
			sb.append("                                     document.body.appendChild(link);\r\n");
			sb.append("                                     link.click();\r\n");
			sb.append("                                     document.body.removeChild(link);\r\n");
			sb.append("                             })\r\n");
			sb.append("                         },\r\n");

			sb.append("                         upload(){\r\n");
			sb.append("                            this.$refs['upload'].submit();\r\n");
			sb.append("                         },\r\n");

			//sb.append("                         beforeUpload () {\r\n");
			//sb.append("                             this.uploadData = { F_ModuleId: this.$route.meta.moduleid };\r\n");
			//sb.append("                         },\r\n");

			sb.append("                         successUpload (res) {\r\n");
			sb.append("                             if(res.code === 0)  {this.$message.success($this.$t(\"deletePrompt.importComplete\")); this.getListData(); } else this.$message.error(res.msg);\r\n");
			sb.append("                         },\r\n");
		}

		if (colModel.getIsTree() > 0)
		{

			sb.append("                        /* 获取树形菜单数据 */\r\n");
			sb.append("                        getTreeData(){\r\n");
			sb.append("                            let id = '';\r\n");
			sb.append("                            request({\r\n");
			sb.append("                                url: baseUrl + '/data-sources/" + StringUtils.defaultIfEmpty(MapUtils.getString(colModel.getTreeForm(), "treeSourceId"), "localDB") + "/tree',\r\n");
			sb.append("                                method: 'get',\r\n");

			if (!StringUtil.isEmpty(colModel.getTreeForm().get("treeSql")))
			{
				sb.append("                                params: { sql:'" + MapUtils.getString(colModel.getTreeForm(), "treeSql", "").replace("\r\n"," ") + "', field:'" + colModel.getTreeForm().get("treefieldId") + "',parentfield:'" + colModel.getTreeForm().get("treeParentId") + "' }\r\n");
			}
			else
			{
				sb.append("                                params: { field:'" + colModel.getTreeForm().get("treefieldId") + "',parentfield:'" + colModel.getTreeForm().get("treeParentId") + "'}\r\n");
			}

			sb.append("                            }).then(res =>{\r\n");
			sb.append("                                this.treeData = res.data.data\r\n");
			sb.append("                                this.$nextTick(function () {\r\n");
			sb.append("                                    this.$refs." + bModel.getName() + "Tree.setCurrentKey(this.treeData[0]?." + colModel.getTreeForm().get("treefieldId") + ");\r\n");
			sb.append("                                })\r\n");
			sb.append("                            })\r\n");
			sb.append("                        },\r\n");

			//树结构绑定的是数据源
			//if (!colModel.TreeForm.TreeSql.IsNull())
			//{
			//    sb.append("                        /* 获取树形菜单数据 */\r\n");
			//    sb.append("                        getTreeData(){\r\n");
			//    sb.append("                            request({\r\n");
			//    sb.append("                                url: baseUrl + '/data-sources/" + colModel.TreeForm.TreeSourceId + "/tree',\r\n");
			//    sb.append("                                method: 'get',\r\n");
			//    sb.append("                                params: { field:'" + colModel.TreeForm.TreefieldId + "',parentfield:'" + colModel.TreeForm.TreeParentId + "'}\r\n");
			//    sb.append("                            }).then(res =>{\r\n");
			//    sb.append("                                this.treeData = res.data.data\r\n");
			//    sb.append("                                this.$nextTick(function () {\r\n");
			//    sb.append("                                    this.$refs." + bModel.name + "Tree.setCurrentKey(this.treeData[0]." + colModel.TreeForm.TreefieldId + ");\r\n");
			//    sb.append("                                })\r\n");
			//    sb.append("                            })\r\n");
			//    sb.append("                        },\r\n");


			//}
			//else // 树结构如果用的是sql
			//{
			//    sb.append("                        /* 获取树形菜单数据 */\r\n");
			//    sb.append("                        getTreeData(){\r\n");
			//    sb.append("                            request({\r\n");
			//    sb.append("                                url: baseUrl + '/database-links/" + dbLinkId + "/tree',\r\n");
			//    sb.append("                                method: 'get',\r\n");
			//    sb.append("                                params: { sql:'"+colModel.TreeForm.TreeSql.Replace("\r\n"," ")+"', field:'" + colModel.TreeForm.TreefieldId + "',parentfield:'" + colModel.TreeForm.TreeParentId + "' }\r\n");
			//    sb.append("                            }).then(res =>{\r\n");
			//    sb.append("                                this.treeData = res.data.data\r\n");
			//    sb.append("                                this.$nextTick(function () {\r\n");
			//    sb.append("                                    this.$refs." + bModel.name + "Tree.setCurrentKey(this.treeData[0]." + colModel.TreeForm.TreefieldId + ");\r\n");
			//    sb.append("                                })\r\n");
			//    sb.append("                            })\r\n");
			//    sb.append("                        },\r\n");

			//}

			sb.append("                        /* 选择树加载列表数据 */\r\n");
			sb.append("                        handleNodeClick(data) {\r\n");
			sb.append("                            this.searchParam ={\r\n");
			sb.append("                                " + colModel.getTreeForm().get("treefieldId") + " : data." + colModel.getTreeForm().get("treefieldId") + "\r\n");
			sb.append("                            }\r\n");
			sb.append("                            this.treeSelect = data." + colModel.getTreeForm().get("treefieldId") + "\r\n");
			sb.append("                            this.getListData()\r\n");
			sb.append("                        },\r\n");

		}
		if (StringUtil.equalsIgnoreCase(colModel.getIsPage(), "1"))
		{
			//-------------------如果是分页的获取数据方法----------------------
			sb.append("                         /* 获取公司用户数据 */\r\n");
			sb.append("                         getListData() {\r\n");
			sb.append("                         	if(!this.searchParam.order){\r\n");
			sb.append("                         		this.searchParam.orderfield = this.defaultOrderfield;\r\n");
			sb.append("                         		this.searchParam.order = this.defaultOrder;\r\n");
			sb.append("                         	}\r\n");
			if (totalData.size() > 0) {
				sb.append("                                this.option.showSummary = false;\r\n");
			}
			sb.append("                            let params = this.changeSearchParams();\r\n");
			sb.append("                            request({\r\n");
			sb.append("                                url: baseUrl + '/" + lowerServiceName + "',\r\n");
			sb.append("                                method: 'get',\r\n");
			sb.append("                                params: params\r\n");
			sb.append("                            }).then(res =>{\r\n");
			sb.append("                                this.listData = res.data.data.Rows\r\n");
			sb.append("                                this.page.total = res.data.data.Total;\r\n");
			if (totalData.size() > 0) {
				sb.append("                                this.option.showSummary = true;\r\n");
			}
			sb.append("                            })\r\n");
			sb.append("                         },\r\n");


			sb.append("                         /* 页面加载 */\r\n");
			sb.append("                         onPageLoad(page) {\r\n");
			sb.append("                            this.searchParam.limit = page.currentPage;\r\n");
			sb.append("                            this.searchParam.size = page.pageSize;\r\n");
			sb.append("                            this.getListData();\r\n");
			sb.append("                         },\r\n");




//			sb.append("                          /* 查询 */\r\n");
//			sb.append("                         searchClick() {\r\n");
//
//			sb.append("                            this.searchParam.limit = 1\r\n");
//			sb.append("                            this.searchParam.order = null\r\n");
//			sb.append("                            this.searchParam.orderfield = null\r\n");
//			sb.append("                            this.searchParam.orderfield = null\r\n");
//			sb.append("                            this.getListData()\r\n");
//			sb.append("                         },\r\n");
		}
		else
		{
			//-------------------不分页的获取数据方法----------------------
			sb.append("                         /* 获取公司用户数据 */\r\n");
			sb.append("                         getListData() {\r\n");
			if (totalData.size() > 0) {
				sb.append("                                this.option.showSummary = false;\r\n");
			}
			sb.append("                            let params = this.changeSearchParams();\r\n");
			sb.append("                            request({\r\n");
			sb.append("                                url: baseUrl + '/" + lowerServiceName + "',\r\n");
			sb.append("                                method: 'get',\r\n");
			sb.append("                                params: params\r\n");
			sb.append("                            }).then(res =>{\r\n");
			sb.append("                                this.listData = res.data.data\r\n");
			if (totalData.size() > 0) {
				sb.append("                                this.option.showSummary = true;\r\n");
			}
			sb.append("                            })\r\n");
			sb.append("                         },\r\n");





//			sb.append("                          /* 查询 */\r\n");
//			sb.append("                         searchClick() {\r\n");
//			sb.append("                            this.searchParam.order = null\r\n");
//			sb.append("                            this.searchParam.orderfield = null\r\n");
//			sb.append("                            this.getListData()\r\n");
//			sb.append("                         },\r\n");


		}

//		sb.append("                          /* 查询表单重置 */\r\n");
//		sb.append("                         searchReset() {\r\n");
//		sb.append("                            this.getListData()\r\n");
//		sb.append("                         },\r\n");


		sb.append("                          /*查看*/\r\n");
		sb.append("                         viewForm(val) {\r\n");
		sb.append("                           this.flag = true;\r\n");
		sb.append("                           this.isEdit = false;\r\n");
		sb.append("                           this.disabled = true;\r\n");
		sb.append("                           this.keyValue = val." + pk + "; \r\n");
		sb.append("                         },\r\n");

		sb.append("                          /* 编辑 */\r\n");
		sb.append("                         editForm(val) {\r\n");
		sb.append("                           this.flag = true; \r\n");
		sb.append("                           this.isEdit = true;\r\n");
		sb.append("                           this.disabled = false;\r\n");
		sb.append("                           this.keyValue = val." + pk + "; \r\n");
		sb.append("                         },\r\n");

		sb.append("                          /* 打开表单 */\r\n");
		sb.append("                         openForm(){\r\n");
		sb.append("							  if(!this.isWorkflowForm){\r\n");
		sb.append("                             //不处理工作流表单时候，表单类型重置\r\n");
		sb.append("                             window.localStorage.setItem('systemFormType',0);\r\n");
		sb.append("                           }\r\n");
		sb.append("                           this.disabled = false;\r\n");
		sb.append("                           this.keyValue = null; \r\n");
		sb.append("                           this.flag = true; \r\n");
		sb.append("                           this.isEdit = true; \r\n");
		sb.append("                         },\r\n");

		sb.append("                          /* 删除 */\r\n");
		sb.append("                         deleteForm(val) {\r\n");
		sb.append("                            this.$confirm(this.$t(\"deletePrompt.promptContent\"), this.$t(\"tip\"), {\r\n");
		sb.append("                              confirmButtonText: this.$t(\"buttonModule.modalSureBtn\"),\r\n");
		sb.append("                              cancelButtonText: this.$t(\"editorModule.cancel\"),\r\n");
		sb.append("                              type: \"warning\",\r\n");
		sb.append("                             }).then(() => {\r\n");
		sb.append("                                 request({\r\n");
		sb.append("                                     url: baseUrl + \"/" + lowerServiceName + "/\" + val." + pk + ",\r\n");
		sb.append("                                     method: \"delete\",\r\n");
		sb.append("                                 }).then((res) => {\r\n");
		sb.append("                                     this.getListData()\r\n");
		sb.append("                                     this.$notify({\r\n");
		sb.append("                                      title: this.$t(\"Notice.hintSuccess\"),\r\n");
		sb.append("                                      message: this.$t(\"deletePrompt.successDeleted\"),\r\n");
		sb.append("                                      type: \"success\",\r\n");
		sb.append("                                     });\r\n");
		sb.append("                                 });\r\n");
		sb.append("                             });\r\n");
		sb.append("                         },\r\n");

		sb.append("                          /* 分页 */\r\n");
		sb.append("                         sortChange(data) {\r\n");
		sb.append("                         	if(data.order){\r\n");
		sb.append("                         		let order= getOrder(data.order);\r\n");
		sb.append("                         		this.searchParam.order = order;\r\n");
		sb.append("                         		this.searchParam.orderfield = data.prop;\r\n");
		sb.append("                         	}else{\r\n");
		sb.append("                         		this.searchParam.order = this.defaultOrder;\r\n");
		sb.append("                         		this.searchParam.orderfield = this.defaultOrderfield;\r\n");
		sb.append("                         	}\r\n");
		sb.append("                         	this.getListData()\r\n");
		sb.append("                         },\r\n");

		sb.append("                          /* 弹窗回调 */\r\n");
		sb.append("                          dialogChange(b){\r\n");
		sb.append("                              this.flag = false;\r\n");
		sb.append("                              this.$nextTick(()=>{\r\n");
		sb.append("                              this.getListData();\r\n");
		sb.append("                         })},\r\n");

		//导出
		if (colModel.getButtonList().stream().anyMatch(x -> MapUtils.getBoolean(x, "checked") && StringUtil.equalsIgnoreCase(MapUtils.getString(x, "val"), "export")))
		{
			sb.append("                          /* 导出 */\r\n");
			sb.append("                          tableExport(){\r\n");
			sb.append("                            this.$refs[\""+bModel.getName()+"Table\"].rowExcel()\r\n");
			sb.append("                            return;\r\n");
			sb.append("                         },\r\n");
		}
		sb.append("                          /* 查询 */\r\n");
		sb.append("                           searchClick(params) {\r\n");
		sb.append("                            this.page.currentPage=1;\r\n");
		sb.append("                            this.searchParam.limit = 1;\r\n");
		sb.append("                            this.searchParam.size = this.page.pageSize;\r\n");
		sb.append("                            this.searchParam = params;\r\n");
		sb.append("                            this.getListData()\r\n");
		sb.append("                         },\r\n");

		sb.append("                           /* 查询表单重置 */\r\n");
		sb.append("                           searchReset() {\r\n");
		sb.append("                            for (const key in this.searchParam) {\r\n");
		sb.append("                                 if(this.searchParam[key]){\r\n");
		sb.append("                                     this.searchParam[key] = null;\r\n");
		sb.append("                                 }\r\n");
		sb.append("                            }\r\n");
		sb.append("                            this.page.currentPage=1;\r\n");
		sb.append("                            this.searchParam.limit = 1;\r\n");
		sb.append("                            this.searchParam.size = this.page.pageSize;\r\n");
		sb.append("                            this.getListData();\r\n");
		sb.append("                         },\r\n");

		sb.append(batchDeleteMethodStr);

		//---------------method over-----------------



		sb.append("         }\r\n");
		sb.append("     }\r\n");
		sb.append("</script>\r\n");

		sb.append("<style scoped>\r\n");

		//导入
		if (colModel.getButtonList().stream().anyMatch(x -> MapUtils.getBoolean(x, "checked") && StringUtil.equalsIgnoreCase(MapUtils.getString(x, "val"), "import")))
		{
			sb.append("div /deep/ .el-upload{\r\n");
			sb.append("   width: 100%;\r\n");
			sb.append("}\r\n");
			sb.append("div /deep/ .el-upload-dragger{\r\n");
			sb.append("   width: 100%;\r\n");
			sb.append("}\r\n");
		}

		sb.append(".searchBox {\r\n");
		sb.append("   width: calc(100% - 218px);\r\n");
		sb.append("   display: inline-block;\r\n");
		sb.append("}\r\n");

		sb.append(".main-container{\r\n");
		sb.append("   height: 100%!important;\r\n");
		sb.append("   padding: 0 8px!important;\r\n");
		sb.append("}\r\n");

		sb.append("div /deep/ .custom-tree-node span{\r\n");
		sb.append("   font-size: 14px;\r\n");
		sb.append("   padding-left: 10px;\r\n");
		sb.append("}\r\n");

		sb.append("div /deep/ .custom-tree-node i{\r\n");
		sb.append("   font-size: 12px;\r\n");
		sb.append("}\r\n");

		sb.append("div /deep/ .el-dialog__body{\r\n");
		sb.append("height: 70vh;\r\n");
		sb.append("overflow: scroll;\r\n");
		sb.append("}\r\n");

		sb.append("</style>\r\n");

		return sb.toString();
	}

	public Map<String, String> buildResultCode(Map<String, StringBuilder> resultCodeMap) {
		Map<String, String> resultMap = new HashMap<>(16);
		resultMap.put("controllerCode", MapUtils.getString(resultCodeMap, "/templates/controller.java.vm"));
		resultMap.put("dbConnectionCode", "");
		resultMap.put("dbFlagCode", "");
		resultMap.put("entityCode", MapUtils.getString(resultCodeMap, "/templates/entity.java.vm"));
		resultMap.put("formHTML", "");
		resultMap.put("forminputDtoCode", MapUtils.getString(resultCodeMap, "/templates/saveFormDataDto.java.vm"));
		resultMap.put("formoutputDtoCode", MapUtils.getString(resultCodeMap, "/templates/formDataVo.java.vm"));
		resultMap.put("irepositoryCode", MapUtils.getString(resultCodeMap, "/templates/mapper.java.vm"));
		resultMap.put("iserviceCode", MapUtils.getString(resultCodeMap, "/templates/service.java.vm"));
//		resultMap.put("listHTML", "");
		resultMap.put("pageinputDtoCode", MapUtils.getString(resultCodeMap, "/templates/listDto.java.vm"));
		resultMap.put("pageoutputDtoCode", MapUtils.getString(resultCodeMap, "/templates/listVo.java.vm"));
		resultMap.put("repositoryCode", MapUtils.getString(resultCodeMap, "/templates/mapper.xml.vm"));
		resultMap.put("serviceCode", MapUtils.getString(resultCodeMap, "/templates/serviceImpl.java.vm"));
		resultMap.put("subserviceCode", MapUtils.getString(resultCodeMap, "/templates/subServiceImpl.java.vm"));
		resultMap.put("subiserviceCode", MapUtils.getString(resultCodeMap, "/templates/subService.java.vm"));
		return resultMap;
	}

	private Map<String, Object> findFieldConfig(List<Map<String, Object>> formDataList, String column) {
		for (Map<String, Object> formData : formDataList) {
			Map<String, Object> config = MapUtils.getMap(formData, FormConstants.CONFIG);
			Map<String, Object> tabsMap = MapUtils.getMap(config, "childrenObj");
			if (tabsMap != null) {
				for (Object obj : tabsMap.values()) {
					List<Map<String, Object>> tabFieldList = (List<Map<String, Object>>) obj;
					for (Map<String, Object> tabField : tabFieldList) {
						Map<String, Object> tabConfig = MapUtils.getMap(tabField, FormConstants.CONFIG);
						if (StringUtil.equalsIgnoreCase(column, MapUtils.getString(tabConfig, FormConstants.BIND_TABLE_FIELD))) {
							return tabField;
						}
					}
				}
			} else {
				if (StringUtil.equalsIgnoreCase(column, MapUtils.getString(config, FormConstants.BIND_TABLE_FIELD))) {
					return formData;
				}
			}
		}
		return null;
	}
}